﻿using Microsoft.EntityFrameworkCore.Storage;
using OpenMms.Domain.ReponseModels;
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
using X.PagedList;

namespace OpenMms.Domain.Interface
{
    /// <summary>
    /// Write
    /// </summary>
    /// <typeparam name="TEntity"></typeparam>
    public interface IBLLConstruct<TEntity> where TEntity : class, new()
    {
        #region 事务
        IDbContextTransaction BeginTrans();

        void LockRow(int id = 0);
        #endregion

        #region 返回Model
        /// <summary>
        /// 按主键查询一个实体
        /// </summary>
        /// <param name="id">主键</param>
        /// <returns></returns>
        TEntity Find(int id);
        /// <summary>
        /// 按主键查询一个实体 异步
        /// </summary>
        /// <param name="id">主键</param>
        /// <returns></returns>
        Task<TEntity> FindAsync(int id);
        /// <summary>
        /// 按条件查询一个实体
        /// </summary>
        /// <param name="where">条件</param>
        /// <returns></returns>
        TEntity Find(Expression<Func<TEntity, bool>> where);
        /// <summary>
        /// 按条件查询一个实体 异步
        /// </summary>
        /// <param name="where">条件</param>
        /// <returns></returns>
        Task<TEntity> FindAsync(Expression<Func<TEntity, bool>> where);

        /// 查询返回自定义model
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="where"></param>
        /// <param name="select"></param>
        /// <returns></returns>
        IList<T> DesignQuery<T>(Expression<Func<TEntity, bool>> where, Expression<Func<TEntity, T>> select);
        /// 查询返回自定义model 异步
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="where"></param>
        /// <param name="select"></param>
        /// <returns></returns>
        Task<IList<T>> DesignQueryAsync<T>(Expression<Func<TEntity, bool>> where, Expression<Func<TEntity, T>> select);
        #endregion

        #region 返回List
        /// <summary>
        /// 按条件查询List 
        /// </summary>
        /// <param name="where">条件</param>
        /// <returns></returns>
        List<TEntity> Query(Expression<Func<TEntity, bool>> where);
        /// <summary>
        /// 按条件查询List 异步
        /// </summary>
        /// <param name="where"></param>
        /// <returns></returns>
        Task<List<TEntity>> QueryAsync(Expression<Func<TEntity, bool>> where);
        /// <summary>
        /// 按条件及指定字段升序返回指定数目一个实体列表
        /// </summary>
        /// <typeparam name="type"></typeparam>
        /// <param name="where">lambda条件表达式</param>
        /// <param name="sort">排序字段</param>
        /// <param name="n">要获取的数量</param>
        /// <returns>实体列表</returns>
        List<TEntity> Query<type>(Expression<Func<TEntity, bool>> where, Expression<Func<TEntity, type>> sort, int n);
        /// <summary>
        /// 按条件及指定字段升序返回指定数目一个实体列表 异步
        /// </summary>
        /// <typeparam name="type"></typeparam>
        /// <param name="where">lambda条件表达式</param>
        /// <param name="sort">排序字段</param>
        /// <param name="n">要获取的数量</param>
        /// <returns>实体列表</returns>
        Task<List<TEntity>> QueryAsync<type>(Expression<Func<TEntity, bool>> where, Expression<Func<TEntity, type>> sort, int n);

        /// <summary>
        /// 分页查询 异步
        /// </summary>
        /// <typeparam name="TKey">排序字段</typeparam>
        /// <param name="where">条件</param>
        /// <param name="pageIndex">当前页</param>
        /// <param name="keySelector">排序条件</param>
        /// <param name="isAsc">是否升序</param>
        /// <returns></returns>
        Task<IPagedList<TEntity>> PageQueryAsync<TKey>(Expression<Func<TEntity, bool>> where, int? pageIndex, Expression<Func<TEntity, TKey>> keySelector, bool isAsc);
        #endregion

        #region 统计
        /// <summary>
        /// 按条件统计
        /// </summary>
        /// <param name="where"></param>
        /// <returns></returns>
        int Count(Expression<Func<TEntity, bool>> where);

        /// <summary>
        /// 按条件统计 异步
        /// </summary>
        /// <param name="where"></param>
        /// <returns></returns>
        Task<int> CountAsync(Expression<Func<TEntity, bool>> where);
        #endregion

        #region 更新
        /// <summary>
        /// 保存
        /// </summary>
        /// <returns></returns>
        int SaveChanges();
        /// <summary>
        /// 保存 异步
        /// </summary>
        /// <returns></returns>
        Task<int> SaveChangesAsync();
        /// <summary>
        /// 更新所有属性
        /// </summary>
        /// <param name="entity"></param>
        bool Update(TEntity entity);
        // <summary>
        /// 实现按需要只更新部分更新
        /// <para>如：Update(u =>u.Id==1,u =>new User{Name="ok"});</para>
        /// </summary>
        /// <param name="where">The where.</param>
        /// <param name="entity">The entity.</param>
        int Update(Expression<Func<TEntity, bool>> where, Expression<Func<TEntity, TEntity>> entity);
        // <summary>
        /// 实现按需要只更新部分更新 异步
        /// <para>如：Update(u =>u.Id==1,u =>new User{Name="ok"});</para>
        /// </summary>
        /// <param name="where">The where.</param>
        /// <param name="entity">The entity.</param>
        Task<int> UpdateAsync(Expression<Func<TEntity, bool>> where, Expression<Func<TEntity, TEntity>> entity);
        #endregion

        #region 写入
        /// <summary>
        /// 写入
        /// </summary>
        /// <param name="model"></param>
        void Insert(TEntity model);
        /// <summary>
        /// 写入 异步
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        Task InsertAsync(TEntity model);
        #endregion
    }
}
